package com.hexacta.hrs;

import java.io.File;
import java.net.URL;
import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.io.FileUtils;
import org.codehaus.cargo.container.InstalledLocalContainer;
import org.codehaus.cargo.container.configuration.builder.ConfigurationEntryType;
import org.codehaus.cargo.container.configuration.entry.DataSource;
import org.codehaus.cargo.container.deployable.Deployable;
import org.codehaus.cargo.container.installer.Installer;
import org.codehaus.cargo.container.installer.ZipURLInstaller;
import org.codehaus.cargo.container.property.ServletPropertySet;
import org.codehaus.cargo.container.property.TransactionSupport;
import org.codehaus.cargo.container.spi.configuration.AbstractLocalConfiguration;
import org.codehaus.cargo.container.tomcat.Tomcat5xInstalledLocalContainer;
import org.codehaus.cargo.container.tomcat.Tomcat5xStandaloneLocalConfiguration;
import org.codehaus.cargo.container.tomcat.TomcatWAR;
import org.codehaus.cargo.util.log.FileLogger;
import org.junit.Assert;

/**
 * Tomcat Fixture is a delegate object responsible for deploying the
 * web-application, starting and stopping a Tomcat instance. It is a wrapper on
 * the Cargo API, and so simplifies the code that is present in the test cases.
 * 
 * @author tpollak
 */
public class TomcatFixture {
    public static final String CARGO_PORT = "8100";

    public static final String TOMCAT_URL = "http://apache.patan.com.ar/tomcat/tomcat-5/v5.5.28/bin/apache-tomcat-5.5.28.zip";

    private InstalledLocalContainer container;

    private BasicDataSource dataSource;

    public void setDataSource(BasicDataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setUp() throws Exception {
        this.container = this.initializeTomcat();
        this.container.start();
    }

    public void tearDown() {
        if (this.container != null) {
            this.container.stop();
        }
    }

    private InstalledLocalContainer initializeTomcat() throws Exception {
        // Initialize the deploy artifact
        //URL warURL = this.getClass().getResource("/hrs-intranet.war");
        File warFile = new File("target/hrs-intranet.war");
        Assert.assertTrue(warFile.exists());
        Deployable war = new TomcatWAR(warFile.getAbsolutePath());

        // Initialize the configuration
        AbstractLocalConfiguration configuration = new Tomcat5xStandaloneLocalConfiguration("target/tomcat5x");
        configuration.addDeployable(war);
        configuration.setProperty(ServletPropertySet.PORT, CARGO_PORT);
        DataSource dsConfig = new DataSource();
        dsConfig.setId("jdbc/VectricsDb");
        dsConfig.setJndiLocation("jdbc/VectricsDb");
        dsConfig.setConnectionType(ConfigurationEntryType.JDBC_DRIVER);
        dsConfig.setTransactionSupport(TransactionSupport.NO_TRANSACTION);
        dsConfig.setDriverClass(this.dataSource.getDriverClassName());
        dsConfig.setUrl(this.dataSource.getUrl());
        dsConfig.setUsername(this.dataSource.getUsername());
        dsConfig.setPassword(this.dataSource.getPassword());
        Properties props = new Properties();
        props.setProperty("username", this.dataSource.getUsername());
        dsConfig.setConnectionProperties(props);
        configuration.addDataSource(dsConfig);

        // Install Tomcat if necessary
        Installer installer = new ZipURLInstaller(new URL(TOMCAT_URL));
        installer.install();

        // Initialize the server (don't start it yet)
        InstalledLocalContainer container = new Tomcat5xInstalledLocalContainer(configuration);
        container.setHome(installer.getHome());
        container.setLogger(new FileLogger("tomcat5x.log", false));

        // Add the JDBC driver to the server's classpath
        URL jdbcDriverURL = this.getClass().getResource("/mysql-connector-java-5.1.6.jar");
        container.addExtraClasspath(FileUtils.toFile(jdbcDriverURL).getAbsolutePath());
        return container;
    }
}
